package com.gitee.haioa;


import javax.swing.filechooser.FileSystemView;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;

/**
 * @author HaiQiu
 * @since 2023/1/4
 */
public class LinuxShell {

    public static final String SH = "sh";
    public static final String PRE = "/";

    public static final String SPOT = ".";

    public static final String ROOT = "/root";

    /**
     * 脚本父级目录
     */
    public static String PARENT_DESK = "生成脚本";

    /**
     * linux一键运行脚本
     */
    public static final String RUN = "find ./ -type f -name \"*.sh\" -exec {} \\;";

    /**
     * 运行脚本项目路径
     */
    public static String PARENT_PATH = "/opt/zhsw/backend";

    public static final String CD = "cd ";

    public static final String AND = " && ";

    /**
     * 典型设置:
     * java -Xmx3550m -Xms3550m -Xmn2g -Xss128k
     * -Xmx3550m:设置JVM最大可用内存为3550M.
     * -Xms3550m:设置JVM促使内存为3550m.此值可以设置与-Xmx相同,以避免每次垃圾回收完成后JVM重新分配内存.
     */
    public static final String MIN = "512m";
    public static final String MAX = "512m";

    /**
     * 指定运行环境
     */
    public static final String ACTIVE = "pro";

    /**
     * -Xmn2g:设置年轻代大小为2G.整个堆大小=年轻代大小 + 年老代大小 + 持久代大小.持久代一般固定大小为64m,
     * 所以增大年轻代后,将会减小年老代大小.此值对系统性能影响较大,Sun官方推荐配置为整个堆的3/8.
     * -Xss128k:设置每个线程的堆栈大小.JDK5.0以后每个线程堆栈大小为1M,
     * 以前每个线程堆栈大小为256K.更具应用的线程所需内存大小进行 调整.
     * 在相同物理内存下,减小这个值能生成更多的线程.但是操作系统对一个进程内的线程数还是有限制的,不能无限生成,经验值在3000~5000左右.
     */
    public static final String OTHER = "-Xmn700m -Xss16m ";

    public static String getDeskTopPath() {
        FileSystemView view = FileSystemView.getFileSystemView();
        File file = view.getHomeDirectory();
        System.out.println(file.getPath());
        return file.getPath();
    }

    /**
     * 根据路径删除指定的目录或文件，无论存在与否
     *
     * @param sPath 要删除的目录或文件
     * @return 删除成功返回 true，否则返回 false。
     */
    public static boolean deleteFolder(String sPath) {
        boolean flag = false;
        File file = new File(sPath);
        // 判断目录或文件是否存在
        if (!file.exists()) {  // 不存在返回 false
            return flag;
        } else {
            // 判断是否为文件
            if (file.isFile()) {  // 为文件时调用删除文件方法
                return deleteFile(sPath);
            } else {  // 为目录时调用删除目录方法
                return deleteDirectory(sPath);
            }
        }
    }

    /**
     * 删除单个文件
     *
     * @param sPath 被删除文件的文件名
     * @return 单个文件删除成功返回true，否则返回false
     */
    public static boolean deleteFile(String sPath) {
        boolean flag = false;
        File file = new File(sPath);
        // 路径为文件且不为空则进行删除
        if (file.isFile() && file.exists()) {
            file.delete();
            flag = true;
        }
        return flag;
    }

    /**
     * 删除目录（文件夹）以及目录下的文件
     *
     * @param sPath 被删除目录的文件路径
     * @return 目录删除成功返回true，否则返回false
     */
    public static boolean deleteDirectory(String sPath) {
        //如果sPath不以文件分隔符结尾，自动添加文件分隔符
        if (!sPath.endsWith(File.separator)) {
            sPath = sPath + File.separator;
        }
        File dirFile = new File(sPath);
        //如果dir对应的文件不存在，或者不是一个目录，则退出
        if (!dirFile.exists() || !dirFile.isDirectory()) {
            return false;
        }
        boolean flag = true;
        //删除文件夹下的所有文件(包括子目录)
        File[] files = dirFile.listFiles();
        for (int i = 0; i < files.length; i++) {
            //删除子文件
            if (files[i].isFile()) {
                flag = deleteFile(files[i].getAbsolutePath());
                if (!flag) {
                    break;
                }
            } //删除子目录
            else {
                flag = deleteDirectory(files[i].getAbsolutePath());
                if (!flag) {
                    break;
                }
            }
        }
        if (!flag) {
            return false;
        }
        //删除当前目录
        if (dirFile.delete()) {
            return true;
        } else {
            return false;
        }
    }


    public static void createShellFile(String fileName) {
        String deskTopPath = getDeskTopPath();
        String prefix = fileName.substring(0, fileName.lastIndexOf("/"));
        String suffix = fileName.substring(fileName.lastIndexOf("/") + 1);
        String s1 = suffix.substring(0, suffix.lastIndexOf("."));
        String s2 = suffix.substring(suffix.lastIndexOf("."));
        String shellName = deskTopPath + PRE + "生成脚本" + prefix + PRE + s1 + SPOT + SH;
        PARENT_DESK = deskTopPath + PRE + "生成脚本";
        File file = new File(shellName);
        if (!file.exists()) {
            file.getParentFile().mkdirs();
            System.out.println("文件夹创建成功：" + file.getParent());
        } else {
            file.delete();
            System.out.println("删除旧文件：" + file);
            file.getParentFile().delete();
            System.out.println("删除旧文件夹：" + file.getParent());
            file.getParentFile().mkdirs();
            System.out.println("文件夹创建成功：" + file.getParent());
        }
        try {
            boolean newFile = file.createNewFile();
            if (newFile) {
                System.out.println("脚本文件创建成功：" + shellName);
            }
            // write
            FileWriter fw = new FileWriter(file, true);
            BufferedWriter bw = new BufferedWriter(fw);
            bw.write(CD + PARENT_PATH + prefix + AND + "ps -ef | grep " +
                    suffix + " | grep -v grep | awk '{ print $2 }' | xargs kill -9 ; nohup java -Xms" + MIN + " -Xmx" + MAX + " -jar " +
                    suffix + " --spring.profiles.active=" + ACTIVE + " > nohup.out 2>&1 &");
            bw.flush();
            bw.close();
            fw.close();
        } catch (Exception e) {
            e.printStackTrace();
        }

    }


    public static void createShellRunFile() {
        String deskTopPath = getDeskTopPath();
        String shellName = deskTopPath + PRE + "生成脚本" + PRE + "run" + SPOT + SH;
        File file = new File(shellName);
        if (!file.exists()) {
            file.getParentFile().mkdirs();
            System.out.println("文件夹创建成功：" + file.getParent());
        } else {
            file.delete();
            System.out.println("删除旧文件：" + file);
        }
        try {
            boolean newFile = file.createNewFile();
            if (newFile) {
                System.out.println("脚本文件创建成功：" + shellName);
            }
            // write
            FileWriter fw = new FileWriter(file, true);
            BufferedWriter bw = new BufferedWriter(fw);
            bw.write(RUN);
            bw.flush();
            bw.close();
            fw.close();
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}
